/**
 *3D模型场景  龙湖九里晴川
 * */
import * as THREE from 'three';
import cameraTools from '../threeTools/cameraTools';
import renderTools from '../threeTools/renderToos';
import sceneTools from '../threeTools/sceneTools';
import loaderTools from '../threeTools/loaderTools';
import orbitControlsTools from '../threeTools/orbitControlsTools';
import raycasterTools from '../threeTools/raycasterTools';

let buildingAnimateId = -1;// 动画ID
// 滚动材质1
let sceneObj = null;
let cameraObj = null;
const scrollMap = new THREE.TextureLoader().load('models/buildScene/QC/UV3.jpg');
scrollMap.wrapT = THREE.RepeatWrapping;
scrollMap.wrapS = scrollMap.wrapT;
scrollMap.repeat.set(1, 1);
// 滚动材质2
const scrollMap2 = new THREE.TextureLoader().load('models/buildScene/QC/UV2.jpg');
scrollMap2.wrapT = THREE.RepeatWrapping;
scrollMap2.wrapS = scrollMap.wrapT;
scrollMap2.repeat.set(1, 1);
// 处理模型fu.js
function sceneModelFu(scene = new THREE.Scene(), geometry, materials) {
  for (let i = 0; i < materials.length; i++) { materials[i].side = THREE.DoubleSide; }
  materials[0] = new THREE.MeshPhongMaterial({
    transparent: true,
    opacity: 0.4,
    depthWrite: false,
    color: 0x00304e,
  });
  const object = new THREE.Mesh(geometry, materials);
  object.name = '没有线条的空心房';
  scene.add(object);
}
// 处理模型lu.js
function sceneModelLu(scene = new THREE.Scene(), geometry, materials) {
  for (let i = 0; i < materials.length; i++) { materials[i].side = THREE.DoubleSide; }
  materials[0] = new THREE.MeshPhongMaterial({
    map: scrollMap,
    color: 0xffffff,
    specular: 0xffffff,
    shininess: 300,
  });
  const object = new THREE.Mesh(geometry, materials);
  object.name = '实体房的流动效果';
  scene.add(object);
}
// 处理模型lu2.js
function sceneModelLu2(scene = new THREE.Scene(), geometry, materials) {
  for (let i = 0; i < materials.length; i++) { materials[i].side = THREE.DoubleSide; }
  materials[0] = new THREE.MeshPhongMaterial({
    map: scrollMap2, // 设置纹理贴图
    color: 0xffffff, // 线条的十六进制颜色
    specular: 0xffffff, // 设置高亮颜色
    shininess: 300, // 设置亮度
  });
  const object = new THREE.Mesh(geometry, materials);
  object.name = '空心房的流动效果';
  scene.add(object);
}
// 处理模型lumian.js
function sceneModelLumian(scene = new THREE.Scene(), geometry, materials) {
  for (let i = 0; i < materials.length; i++) { materials[i].side = THREE.DoubleSide; }
  materials[0] = new THREE.MeshPhongMaterial({
    transparent: true,
    opacity: 0.2,
    depthWrite: false,
    specular: 0x0054ff,
    color: 0x535ffe,
    emissive: 0x535ffe, // 设置放射光颜色
    shininess: 50,
  });
  const object = new THREE.Mesh(geometry, materials);
  object.name = '实体房的路面';
  scene.add(object);
}
// 处理模型xian.js
function sceneModelXian(scene = new THREE.Scene(), geometry, materials) {
  for (let i = 0; i < materials.length; i++) { materials[i].side = THREE.DoubleSide; }
  // 着色器材料
  materials[0] = new THREE.ShaderMaterial({
    uniforms:
            {
              c: { type: 'f', value: 1 },
              p: { type: 'f', value: 0.2 },
              glowColor: { type: 'c', value: new THREE.Color(0x0060ff) }, // 2ac0ff
              viewVector: { type: 'v3', value: cameraObj.position },
            },
    vertexShader: document.getElementById('vertexShader').textContent, // 顶点着色器的GLSL代码
    fragmentShader: document.getElementById('fragmentShader').textContent, // 片段着色器的GLSL代码
    side: THREE.FrontSide, // 定义表面两侧的哪一个将呈现
    blending: THREE.AdditiveBlending, // 当显示该材料的对象时使用何种混合模式（加法混合）
    transparent: true,
  });
  const object = new THREE.Mesh(geometry, materials);
  object.name = '有线条的实体房';
  object.position.set(0, 0.1, 0);
  scene.add(object);
}
// 处理模型xian2.js
function sceneModelXian2(scene = new THREE.Scene(), geometry, materials) {
  for (let i = 0; i < materials.length; i++) { materials[i].side = THREE.DoubleSide; }
  materials[0] = new THREE.MeshPhongMaterial({
    transparent: true,
    opacity: 0.2,
    depthWrite: false,
    color: 0x00304e,
  });
  const object = new THREE.Mesh(geometry, materials);
  object.name = '有线条的空心房';
  scene.add(object);
}
// 处理模型7
function sceneModelQs2(scene = new THREE.Scene(), geometry, materials) {
  for (let i = 0; i < materials.length; i++) { materials[i].side = THREE.DoubleSide; }
  materials[0] = new THREE.MeshPhongMaterial({
    transparent: true,
    opacity: 0.4,
    depthWrite: false,
    specular: 0x0048ff,
    color: 0x0048ff,
    emissive: 0x0048ff,
    shininess: 300,
  });
  const object = new THREE.Mesh(geometry, materials);
  object.name = '没有线条的实体房';
  object.castShadow = true;// 是否被渲染到阴影映射中
  object.receiveShadow = true;// 材料接受阴影效果
  scene.add(object);
}
// 处理广场模型
function buildGround(scene) {
  const texture1 = new THREE.TextureLoader().load('models/buildScene/QC/dian.png');
  texture1.wrapT = THREE.RepeatWrapping;
  texture1.wrapS = texture1.wrapT;
  texture1.repeat.set(300, 300);
  const material1 = new THREE.MeshPhongMaterial({ map: texture1, transparent: true, opacity: 0.8, side: THREE.DoubleSide });
  const ground = new THREE.Mesh(new THREE.PlaneGeometry(1000, 1000), material1);
  ground.name = '广场';
  ground.scale.set(100, 100, 100);
  ground.position.set(0, 10, 0);
  ground.rotation.set(Math.PI / 2, 0, 0);
  scene.add(ground);
}
// 3D模型渲染
function sceneStart(domId = '', width = 1920, height = 1080) {
  // 实例化渲染器
  const renderObj = renderTools.initRender({ domId, width, height, cleanColor: '#FFFFFF' });
  // 实例化摄像机
  cameraObj = cameraTools.initCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
  cameraObj.position.x = 1000;
  cameraObj.position.y = 1000;
  cameraObj.position.z = 1000;
  // 实例化场景
  sceneObj = sceneTools.initScene();
  const controls = orbitControlsTools.initControls(cameraObj, renderObj.domElement);
  // 环境光
  const light = new THREE.HemisphereLight(0xffffff, 0xffffff, 1.5);
  sceneObj.add(light);
  // 聚合光，使用MeshLaambertMaterial或Phong网孔材料来影响对象
  const spotLight = new THREE.SpotLight(0x0048ff, 2);// 聚光光源，一种能投射锥形阴影区域的点光源
  spotLight.position.set(0, 10, 0);
  spotLight.position.multiplyScalar(700);
  spotLight.shadow.mapSize.width = 1000;
  spotLight.shadow.mapSize.height = 1000;
  spotLight.shadow.camera.near = 200;
  spotLight.shadow.camera.far = 1500;
  spotLight.shadow.camera.fov = 40;
  spotLight.shadow.bias = -0.005;
  sceneObj.add(spotLight);
  sceneObj.scale.set(0.018, 0.018, 0.018);
  // // 场地
  buildGround(sceneObj);
  // 加载模型
  loaderTools.loadJson(['models/buildScene/QC/fu.js'], sceneObj, sceneModelFu);// 没有线条的空心房
  loaderTools.loadJson(['models/buildScene/QC/lu.js'], sceneObj, sceneModelLu);// 实体房的流动效果
  loaderTools.loadJson(['models/buildScene/QC/lu2.js'], sceneObj, sceneModelLu2);// 空心房的流动效果
  loaderTools.loadJson(['models/buildScene/QC/lumian.js'], sceneObj, sceneModelLumian);// 实体房的路面
  loaderTools.loadJson(['models/buildScene/QC/xian.js'], sceneObj, sceneModelXian);// 有线条的实体房
  loaderTools.loadJson(['models/buildScene/QC/xian2.js'], sceneObj, sceneModelXian2);// 有线条的空心房
  loaderTools.loadJson(['models/buildScene/QC/qs2.js'], sceneObj, sceneModelQs2);// 没有线条的实体房
  return renderModel(renderObj, sceneObj, cameraObj, controls);
}
// 停止动画刷新
function sceneStop() {
  window.cancelAnimationFrame(buildingAnimateId);
}
// 渲染模型
function renderModel(render = new THREE.WebGLRenderer(), scene = new THREE.Scene(), camera = new THREE.PerspectiveCamera(), controls = null) {
  if (controls != null) {
    controls.update();
  }
  buildingAnimateId = requestAnimationFrame(() => {
    renderModel(render, scene, camera);
  });
  const timeL = Date.now() * 0.0001;
  const ox = -(timeL * scrollMap.repeat.x) % 1;
  const oy = -(timeL * scrollMap.repeat.y) % 1;
  scrollMap.offset.set(ox, oy);
  const ox2 = -(timeL * scrollMap2.repeat.x) % 1;
  const oy2 = -(timeL * scrollMap2.repeat.y) % 1;
  scrollMap2.offset.set(ox2, oy2);
  scene.rotation.y += 0.0005;
  render.render(scene, camera);
}

// 模型点击事件
function sceneClick(event) {
  const result = raycasterTools.sceneClick(event, cameraObj, sceneObj);
  if (result.status) {
    if (result.data[0].object.name == '没有线条的实体房' || result.data[0].object.name == '有线条的实体房') {
      return true;
    }
  }
  return false;
}

export default {
  sceneStart,
  sceneStop,
  sceneClick,
};
